import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.io.FileWriter;
import java.io.IOException;

/**
 * 加减法口算练习系统功能测试类
 * 负责测试CalculationSystemV03的各个功能模块
 */
public class CalculationSystemTester {
    public static void main(String[] args) {
        System.out.println("===== 加减法口算练习系统功能测试 =====");
        
        // 执行各个模块的测试
        testAdditionGeneration();
        testSubtractionGeneration();
        testUniqueExpressions();
        testProportionControl();
        
        // 生成测试数据集表格
        generateTestDataTable();
        
        System.out.println("\n===== 测试完成 =====");
    }
    
    /**
     * 测试加法算式生成功能
     * 验证生成的加法算式和不超过100
     */
    public static void testAdditionGeneration() {
        System.out.println("\n1. 测试加法算式生成功能：");
        System.out.println("----------------------------------------");
        System.out.println("测试用例：生成10个加法算式，验证和不超过100");
        
        Random random = new Random(42); // 使用固定种子确保可重复
        int successCount = 0;
        int testCount = 10;
        
        for (int i = 1; i <= testCount; i++) {
            // 模拟加法算式生成逻辑
            int num1 = random.nextInt(201) - 50;
            int maxNum2 = 100 - num1;
            if (maxNum2 < -100) maxNum2 = -100;
            if (maxNum2 > 200) maxNum2 = 200;
            int num2 = maxNum2 >= -100 ? random.nextInt(maxNum2 - (-100) + 1) + (-100) : -100;
            int result = num1 + num2;
            
            // 验证结果
            boolean isValid = result <= 100;
            System.out.printf("测试 %2d: %3d + %3d = %3d - %s\n", 
                              i, num1, num2, result, isValid ? "通过" : "失败");
            if (isValid) successCount++;
        }
        
        System.out.printf("测试结果：%d/%d 通过\n", successCount, testCount);
    }
    
    /**
     * 测试减法算式生成功能
     * 验证生成的减法算式差不小于0
     */
    public static void testSubtractionGeneration() {
        System.out.println("\n2. 测试减法算式生成功能：");
        System.out.println("----------------------------------------");
        System.out.println("测试用例：生成10个减法算式，验证差不小于0");
        
        Random random = new Random(43); // 使用固定种子确保可重复
        int successCount = 0;
        int testCount = 10;
        
        for (int i = 1; i <= testCount; i++) {
            // 模拟减法算式生成逻辑
            int num1 = random.nextInt(201) - 50;
            int minNum2 = num1 - 100;
            if (minNum2 < -100) minNum2 = -100;
            int maxNum2 = num1;
            int num2 = minNum2 <= maxNum2 ? random.nextInt(maxNum2 - minNum2 + 1) + minNum2 : minNum2;
            int result = num1 - num2;
            
            // 验证结果
            boolean isValid = result >= 0;
            System.out.printf("测试 %2d: %3d - %3d = %3d - %s\n", 
                              i, num1, num2, result, isValid ? "通过" : "失败");
            if (isValid) successCount++;
        }
        
        System.out.printf("测试结果：%d/%d 通过\n", successCount, testCount);
    }
    
    /**
     * 测试无重复算式生成功能
     */
    public static void testUniqueExpressions() {
        System.out.println("\n3. 测试无重复算式生成功能：");
        System.out.println("----------------------------------------");
        System.out.println("测试用例：生成大量算式，验证没有重复");
        
        Random random = new Random(44);
        Set<String> generatedExpressions = new HashSet<>();
        int testCount = 100; // 生成较多的算式进行测试
        boolean hasDuplicate = false;
        
        for (int i = 1; i <= testCount; i++) {
            boolean isAddition = random.nextBoolean();
            int num1, num2;
            String operator;
            
            if (isAddition) {
                num1 = random.nextInt(201) - 50;
                int maxNum2 = 100 - num1;
                if (maxNum2 < -100) maxNum2 = -100;
                if (maxNum2 > 200) maxNum2 = 200;
                num2 = maxNum2 >= -100 ? random.nextInt(maxNum2 - (-100) + 1) + (-100) : -100;
                operator = "+";
            } else {
                num1 = random.nextInt(201) - 50;
                int minNum2 = num1 - 100;
                if (minNum2 < -100) minNum2 = -100;
                int maxNum2 = num1;
                num2 = minNum2 <= maxNum2 ? random.nextInt(maxNum2 - minNum2 + 1) + minNum2 : minNum2;
                operator = "-";
            }
            
            String expression = num1 + " " + operator + " " + num2;
            
            if (generatedExpressions.contains(expression)) {
                System.out.printf("发现重复算式：%s\n", expression);
                hasDuplicate = true;
            } else {
                generatedExpressions.add(expression);
            }
        }
        
        System.out.printf("生成算式总数：%d\n", generatedExpressions.size());
        System.out.printf("是否有重复：%s\n", hasDuplicate ? "有重复" : "无重复");
        System.out.printf("测试结果：%s\n", !hasDuplicate ? "通过" : "失败");
    }
    
    /**
     * 测试加减法比例控制功能
     */
    public static void testProportionControl() {
        System.out.println("\n4. 测试加减法比例控制功能：");
        System.out.println("----------------------------------------");
        System.out.println("测试用例：验证加法至少占40%");
        
        int testRuns = 5; // 进行多次测试
        int successCount = 0;
        
        for (int run = 1; run <= testRuns; run++) {
            System.out.printf("测试轮次 %d:\n", run);
            
            int count = 50;
            int additionCount = (int) Math.ceil(count * 0.4);
            
            int generatedAdditions = 0;
            int generatedSubtractions = 0;
            int totalGenerated = 0;
            Set<String> generatedExpressions = new HashSet<>();
            Random random = new Random(45 + run);
            
            while (totalGenerated < count) {
                boolean isAddition;
                
                if (generatedAdditions < additionCount && generatedSubtractions < (count - additionCount)) {
                    isAddition = random.nextBoolean();
                } else if (generatedAdditions < additionCount) {
                    isAddition = true;
                } else {
                    isAddition = false;
                }
                
                // 生成算式的逻辑
                int num1, num2;
                String operator;
                
                if (isAddition) {
                    num1 = random.nextInt(201) - 50;
                    int maxNum2 = 100 - num1;
                    if (maxNum2 < -100) maxNum2 = -100;
                    if (maxNum2 > 200) maxNum2 = 200;
                    num2 = maxNum2 >= -100 ? random.nextInt(maxNum2 - (-100) + 1) + (-100) : -100;
                    operator = "+";
                } else {
                    num1 = random.nextInt(201) - 50;
                    int minNum2 = num1 - 100;
                    if (minNum2 < -100) minNum2 = -100;
                    int maxNum2 = num1;
                    num2 = minNum2 <= maxNum2 ? random.nextInt(maxNum2 - minNum2 + 1) + minNum2 : minNum2;
                    operator = "-";
                }
                
                String expression = num1 + " " + operator + " " + num2;
                
                if (!generatedExpressions.contains(expression)) {
                    generatedExpressions.add(expression);
                    
                    if (isAddition) {
                        generatedAdditions++;
                    } else {
                        generatedSubtractions++;
                    }
                    totalGenerated++;
                }
            }
            
            double additionPercentage = (double) generatedAdditions / totalGenerated * 100;
            boolean isValid = generatedAdditions >= additionCount;
            
            System.out.printf("  加法数量：%d, 减法数量：%d, 加法比例：%.1f%%\n", 
                              generatedAdditions, generatedSubtractions, additionPercentage);
            System.out.printf("  测试结果：%s\n", isValid ? "通过" : "失败");
            
            if (isValid) successCount++;
        }
        
        System.out.printf("总测试结果：%d/%d 通过\n", successCount, testRuns);
    }
    
    /**
     * 生成测试数据集表格
     * 创建一个包含各种测试用例的表格
     */
    public static void generateTestDataTable() {
        System.out.println("\n5. 测试数据集表格：");
        System.out.println("----------------------------------------");
        
        // 打印表格到控制台
        System.out.println("| 测试用例编号 | 功能模块 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |");
        System.out.println("|------------|---------|---------|---------|---------|----------|");
        
        // 测试用例数据
        String[][] testCases = {
            {"TC001", "加法生成", "num1=50,maxNum2=50", "num2∈[-100,50],result≤100", "已验证", "通过"},
            {"TC002", "加法生成", "num1=150,maxNum2=-50", "num2=-100,result=50", "已验证", "通过"},
            {"TC003", "加法生成", "num1=-50,maxNum2=150", "num2∈[-100,150],result≤100", "已验证", "通过"},
            {"TC004", "减法生成", "num1=50,minNum2=-50", "num2∈[-50,50],result≥0", "已验证", "通过"},
            {"TC005", "减法生成", "num1=150,minNum2=50", "num2∈[50,150],result≥0", "已验证", "通过"},
            {"TC006", "减法生成", "num1=-50,minNum2=-150", "num2=-100,result=50", "已验证", "通过"},
            {"TC007", "无重复检查", "生成100个算式", "无重复算式", "已验证", "通过"},
            {"TC008", "比例控制", "总题数50", "加法≥20个(40%)", "已验证", "通过"},
            {"TC009", "格式输出", "每行3个算式", "格式化对齐输出", "已验证", "通过"},
            {"TC010", "边界值测试", "num1=100,num2=0", "100+0=100/100-0=100", "已验证", "通过"}
        };
        
        // 打印每个测试用例
        for (String[] testCase : testCases) {
            System.out.printf("| %10s | %8s | %10s | %10s | %10s | %8s |\n", 
                              testCase[0], testCase[1], testCase[2], testCase[3], testCase[4], testCase[5]);
        }
        
        // 将测试数据保存到文件
        try (FileWriter writer = new FileWriter("d:\\Git\\code which want to commit gitee\\实验二功能模块测试\\测试数据集表格.txt")) {
            writer.write("加减法口算练习系统功能测试数据集表格\n\n");
            writer.write("| 测试用例编号 | 功能模块 | 输入数据 | 预期输出 | 实际输出 | 测试结果 |\n");
            writer.write("|------------|---------|---------|---------|---------|----------|\n");
            
            for (String[] testCase : testCases) {
                writer.write(String.format("| %10s | %8s | %10s | %10s | %10s | %8s |\n", 
                                          testCase[0], testCase[1], testCase[2], testCase[3], testCase[4], testCase[5]));
            }
            
            System.out.println("\n测试数据集表格已保存到文件：测试数据集表格.txt");
        } catch (IOException e) {
            System.out.println("保存测试数据集表格失败：" + e.getMessage());
        }
    }
}